/*
 * Copyright (C) 2010 LianHaidong <lianhaidong@gmail.com>
 */

#include <stdlib.h>
#include "utils/static_hash.h"
#include "utils/debug.h"


struct static_hash_list *static_hash_list_create(
		int index_max,
		hash_func_t func,
		hash_compare_t compare)
{
	struct static_hash_list *hl;
	int size;
	
	if (index_max <= 0) {
		msg("index max < 0");
		return NULL;
	}

	if (!func) {
		msg("func == NULL");
		return NULL;
	}

	if (!compare) {
		msg("compare == NULL");
		return NULL;
	}

	size = sizeof(*hl) + sizeof(struct list_head) * index_max;
	hl = calloc(1, size);
	if (!hl) {
		msg("Outof Memory !!!");
		return NULL;
	}

	hl->func = func;
	hl->compare = compare;
	hl->index_max = index_max;

	return hl;
}

void static_hash_list_delete(struct static_hash_list *hl)
{
	free(hl);
}

int static_hash_list_insert(struct static_hash_list *hl, 
                            struct static_hash_node *hn)
{
	int index;

	index = hl->func(hn->key);
	if (index < 0 || index > hl->index_max) {
		msg("Invalid index %d", index);
		return -1;
	}

	list_add_tail(&hn->entry, &hl->node[index]);

	return 0;
}

struct static_hash_node *static_hash_list_find(
		struct static_hash_list *hl, void *key)
{
	int index;
	struct static_hash_node *hn;

	index = hl->func(key);
	if (index < 0 || index > hl->index_max) {
		msg("Invalid index %d", index);
		return NULL;
	}

	list_for_each_entry(hn, &hl->node[index], entry) {
		if (hl->compare(key, hn->key) == 0)
			return hn;
	}

	return NULL;
}

int static_hash_node_del(struct static_hash_node *hn)
{
	list_del(&hn->entry);
	return 0;
}


